package com.fitc;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.swing.SwingWorker;

import com.fitc.json.DatabaseHelper;
import com.fitc.json.Photo;
import com.fitc.ui.Informable;

public class ImageDataWorker extends SwingWorker<Integer, String> {

	private static final int NTHREDS = 5;

	private static final int IMAGES_AT_A_TIME = 10;
	DatabaseHelper db;

	private final Informable informable;

	public ImageDataWorker(Informable informable) {
		this.informable = informable;
	}

	@Override
	protected Integer doInBackground() throws Exception {

		db = new DatabaseHelper();
		List<Photo> photos = new ArrayList<Photo>();

		// Get total number of images
		int size = db.getTotalImageCount();
		int c = 0;
		int imagesDone = db.getProcessedImageCount();

		// Get list of unprocessed photos from db
		do {

			photos = db.getUnProcessedPhotos(IMAGES_AT_A_TIME);

			// process them
			ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);

			for (Photo p : photos) {
				executor.execute(p.getColorData());
			}

			// This will make the executor accept no new threads
			// and finish all existing threads in the queue
			executor.shutdown();

			// Wait until all threads are finish
			while (!executor.isTerminated()) {
			}
			imagesDone =  imagesDone+photos.size();
			// update database
			db.insertImageData(photos);

			// get number of unprocessed images
			int percent = (int) (100.0f * (float) imagesDone / (float) size);
			
			if (c >= 10) {
				setProgress(percent);
				publish("Progress: " + imagesDone + " / " + size);
				c = 0;
			}
			c++;
		} while (photos.size() > 0);

		db.close();
		return 10;
	}

	@Override
	protected void process(List<String> chunks) {
		for (String message : chunks) {
			informable.messageChanged(message);
		}
	}

}
